﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Web;
using System.Web.Mvc;
using System.ServiceModel.Syndication;
using LevenBlog.Core.Data;
using LevenBlog.Core.Entities;
using LevenBlog.Core.Utils;
using LevenBlog.Core.Service;

namespace LevenBlog.Core.Mvc
{
    public enum FeedType
    {
        Rss,
        Atom
    }

    public sealed class FeedResult : ActionResult
    {
        private IDbProvider provider = null;
        private int categoryID = -1;
        private int page = 1;
        private FeedType type = FeedType.Rss;

        public IDbProvider Provider
        {
            get { return provider; }
            set { provider = value; }
        }

        public int CategoryID
        {
            get { return categoryID; }
            set { categoryID = value; }
        }

        public int Page
        {
            get { return page; }
            set { page = value; }
        }

        public FeedType Type
        {
            get { return type; }
            set { type = value; }
        }

        public FeedResult(IDbProvider provider)
        {
            this.provider = provider;
        }

        public override void ExecuteResult(ControllerContext context)
        {
            //UrlHelper url = new UrlHelper(new ViewContext(context, "rss", string.Empty, (context.Controller as Controller).ViewData, (context.Controller as Controller).TempData));
            //UrlHelper url = new UrlHelper(new ViewContext(context, "rss", context.Controller.ViewData, context.Controller.TempData));
            UrlHelper url = (context.Controller as Controller).Url;
            lb_config config = Config.Get(provider);
            IList<lb_category> categoryList = Category.Get(provider);
            IList<lb_blog> blogs = null;
            if (categoryID < 1)
                blogs = Blog.Get(provider, config.blogpage, page, BlogState.Show);
            else
                blogs = Blog.Get(provider, categoryID, config.blogpage, page, BlogState.Show);
            SyndicationFeed syFeed = new SyndicationFeed(config.title, config.intro, new Uri(config.url));
            categoryList = categoryList.Where(c => !c.isurl).ToList();
            foreach (lb_category category in categoryList)
            {
                SyndicationCategory sc = new SyndicationCategory();
                sc.Name = category.name;
                sc.Scheme = category.info;
                sc.Label = category.name;
                syFeed.Categories.Add(sc);
            }
            syFeed.Copyright = new TextSyndicationContent(config.copyright);
            syFeed.ImageUrl = new Uri(string.Format("{0}{1}", config.url.ToFullUrl(), config.logo));
            syFeed.Language = "zh-cn";
            syFeed.Authors.Add(new SyndicationPerson(config.mail, config.master, config.url));
            List<SyndicationItem> items = new List<SyndicationItem>();
            foreach (lb_blog blog in blogs)
            {
                SyndicationItem item = new SyndicationItem();
                item.Authors.Add(new SyndicationPerson(blog.postuser, blog.postuser, config.url.ToFullUrl() + url.RouteUrl(new { controller = "blog", action = "view", id = blog.id.ToString(), page = "1" })));
                item.BaseUri = new Uri(config.url.ToFullUrl() + url.RouteUrl(new { controller = "blog", action = "view", id = blog.id.ToString(), page = "1" }));
                item.Content = new TextSyndicationContent(blog.intro);
                item.Categories.Add(new SyndicationCategory(blog.Category.name));
                item.AddPermalink(new Uri(config.url.ToFullUrl() + url.RouteUrl(new { controller = "blog", action = "view", id = blog.id.ToString(), page = "1" })));
                item.Links.Add(new SyndicationLink(new Uri(config.url.ToFullUrl() + url.RouteUrl(new { controller = "blog", action = "view", id = blog.id.ToString(), page = "1" }))));
                item.Id = blog.id.ToString();
                item.LastUpdatedTime = blog.edittime;
                item.PublishDate = blog.posttime;
                item.Title = new TextSyndicationContent(blog.title);
                items.Add(item);
            }
            syFeed.Items = items;
            //输出
            context.HttpContext.Response.ContentType = "text/xml;charset=utf-8";
            if (type == FeedType.Rss)
            {
                Rss20FeedFormatter rssFormat = new Rss20FeedFormatter(syFeed);
                XmlWriter rssWriter = new XmlTextWriter(context.HttpContext.Response.OutputStream, System.Text.Encoding.UTF8);
                rssFormat.WriteTo(rssWriter);
                rssWriter.Close();
            }
            else if(type==FeedType.Atom)
            {
                Atom10FeedFormatter atomFormat = new Atom10FeedFormatter(syFeed);
                XmlWriter atomWriter = new XmlTextWriter(context.HttpContext.Response.OutputStream, System.Text.Encoding.UTF8);
                atomFormat.WriteTo(atomWriter);
                atomWriter.Close();
            }
        }
    }
}
